package com.itheima.springbootwebtest.interceptor;

import com.itheima.springbootwebtest.context.BaseContext;
import com.itheima.springbootwebtest.properties.JWTProperties;
import com.itheima.springbootwebtest.utils.JWTUtils;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

/**
 * 拦截器
 *
 * @Author mr.luo
 * @Date 14 4月 2025 15:10
 */
@Slf4j
@Component
public class WebInterceptor implements HandlerInterceptor {
    @Autowired
    private JWTProperties jwtProperties;

    //    preHandle : 目标方法执行前执行  返回值为true表示放行，false表示拦截
//    postHandle : 目标方法执行后执行
//    afterCompletion : 视图渲染完成后执行
/*
动态方法：通常指由开发者定义的、通过 @RequestMapping、@GetMapping 等注解标记的 Controller 方法。
这些方法需要进行权限校验（如 JWT 验证）。
非动态方法：通常是框架或服务器处理的静态资源、配置文件、或者其他非业务逻辑的请求（如 favicon.ico、/swagger-ui.html 等），
这些请求不需要权限校验。

1. HttpServletRequest request 用于获取请求相关的所有信息
2、HttpServletResponse：用于控制响应行为（状态码、头、错误信息）。
3、Object handler：用于判断请求是否指向 Controller 方法，从而精准拦截业务接口。
*/
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            // 当前拦截到的不是 Controller 方法，直接放行 // 非动态方法，直接放行
            return true;
        }
        log.info("拦截器拦截controller请求：{}", request.getRequestURI());
        String token = request.getHeader(jwtProperties.getTokenName());
        log.info("获取到jwt令牌为: {}", token);
        log.info("开始校验jwt令牌");
        if (token == null) {
            log.info("jwt令牌为空，返回错误结果");
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return false;
        } else {
            try {
                Claims claims = JWTUtils.parseJWT(jwtProperties.getSecretKey(), token);
                log.info("解析到当前用户为: {}", claims);
                Integer id = Integer.valueOf(claims.get("id").toString());
                log.info("解析到当前用户id为: {}", id);
                BaseContext.setThreadLocal(id);
            } catch (Exception e) {
                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                return false;
            }
        }
        return true;
    }

//    @Override    //  目标方法执行后执行
//    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
//    }

    @Override   // 视图渲染完成后执行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        BaseContext.removeThreadLocal();
    }
}
